/*
 * Copyright the original author or authors.
 *
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.mozilla.org/MPL/MPL-1.1.html *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors:
 *   Russell Weir damonsbane/gmail dot com
 */
package hxbase.flash.net;
import hxbase.events.Event;
import hxbase.flash.events.EventTypes;
import hxbase.flash.IFlashWrapper;

class NetStreamEvents extends EventGroup {
	var onNetStatus	: Event<Dynamic->Void>;
	var onAsyncError : Event<Dynamic->Void>;
	var onIoError  : Event<Dynamic->Void>;

	override private function init() {
		onNetStatus = new Event<Dynamic->Void>(this);
		onAsyncError = new Event<Dynamic->Void>(this);
		onIoError  = new Event<Dynamic->Void>(this);
	}
}

class NetStream extends hxbase.flash.events.EventDispatcher<NetStreamEvents>,
#if flash9
		implements IFlashWrapper<flash.net.NetStream>
#else flash
		implements IFlashWrapper<flash.NetStream>
#end
{
	public var audioCodec(getAudioCodec,null) : Int;
	public var bufferLength(getBufferLength,null) : Float;
	public var bufferTime : Float;
	public var bytesLoaded(getBytesLoaded,null) : Int;
	public var bytesTotal(getBytesTotal,null) : Int;
	public var checkPolicyFile : Bool;
	public var client : Dynamic;
	public var currentFps(getCurrentFps,null) : Float;
	public var decodedFrames(getDecodedFrames,null) : Int;
	public var liveDelay(getLiveDelay,null) : Float;
	public var objectEncoding(getObjectEncoding,null) : Int;
	public var soundTransform : flash.media.SoundTransform;
	public var time(getTime,null) : Float;
	public var videoCodec(getVideoCodec,null) : Int;

	var nc : NetConnection;
	var ns(default,null) : flash.net.NetStream;

	public function new(nc : NetConnection) {
		super();
		events = new NetStreamEvents();
		this.nc = nc;
#if flash9
		ns = new flash.net.NetStream(nc.getObject());
#else flash
		ns = new flash.NetStream(nc.getObject());
#end
	}

	public function attachAudio(microphone : hxbase.flash.media.Microphone) : Void {
		ns.attachAudio(microphone.getObject());
	}
	public function attachCamera(camera : hxbase.flash.media.Camera, ?snapshotMillisec : Int) : Void {
#if flash9
		ns.attachCamera(camera.getObject(), snapshotMillisec);
#else flash
		ns.attachVideo(camera.getObject(), snapshotMillisec);
#end
	}
	public function close() : Void {
		ns.close();
	}
	public function pause() : Void {
		ns.pause();
	}
	public function play(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void {
		ns.play(p1,p2,p3,p4,p5);
	}
	public function publish(?name : String, ?type : String) : Void {
		ns.publish(name, type);
	}
	public function receiveAudio(flag : Bool) : Void {
		ns.receiveAudio(flag);
	}
	public function receiveVideo(flag : Bool) : Void {
		ns.receiveVideo(flag);
	}
	public function resume() : Void {
		ns.resume();
	}
	public function seek(offset : Float) : Void {
		ns.seek(offset);
	}
	public function send(handlerName : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void {
		ns.send(handlerName, p1, p2, p3, p4, p5);
	}
	public function togglePause() : Void {
		ns.togglePause();
	}

	public function getObject() {
		return ns;
	}

	////////////////////////////////////////////////////
	////		Wrapped accessors		////
	////////////////////////////////////////////////////
	public function getAudioCodec() : Int {
		return ns.audioCodec;
	}
	public function getBufferLength() : Float{
		return ns.bufferLength;
	}
	//public function getBufferTime : Float{ return ns. }
	public function getBytesLoaded() : Int {
		return ns.bytesLoaded;
	}
	public function getBytesTotal() : Int {
		return ns.bytesTotal;
	}
	//public function getCheckPolicyFile : Bool{ return ns. }
	//public function getClient : Dynamic{ return ns. }
	public function getCurrentFps() : Float {
#if flash9
		return ns.currentFPS;
#else flash
		return ns.currentFps;
#end
	}
	public function getDecodedFrames() : Int {
		return ns.decodedFrames;
	}
	public function getLiveDelay() : Float {
		return ns.liveDelay;
	}
	public function getObjectEncoding() : Int {
		return ns.objectEncoding;
	}
	public function getSoundTransform() : flash.media.SoundTransform {
		return ns.soundTransform;
	}
	public function getTime() : Float {
		return ns.time;
	}
	public function getVideoCodec() : Int {
		return ns.videoCodec;
	}

	////////////////////////////////////////////////////
	////		Events				////
	////////////////////////////////////////////////////
	public function addEventListener(type :String, listener : Dynamic->Void) {
		switch(type) {
		case EventTypes.ASYNC_ERROR:
			checkSubscribed(ns, type, onAsyncError);
			events.onAsyncError.bind(null, listener);
		case EventTypes.IO_ERROR:
			checkSubscribed(ns, type, onIoError);
			events.onIoError.bind(null, listener);
		case EventTypes.NET_STATUS:
			checkSubscribed(ns, type, onNetStatus);
			events.onNetStatus.bind(null, listener);
		default:
			trace("["+here.methodName+"] Unknown event "+type);
		}
	}

	function onAsyncError(e) {
		events.onAsyncError.call(e);
	}

	function onIoError(e) {
		events.onIoError.call(e);
	}

	function onNetStatus(e) {
		events.onNetStatus.call(e);
	}

}